﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.Runtime.Serialization;

namespace TestXNA3.Components
{
    [Serializable]
    public class PhysicsComponent : Component
    {
        public class PhysicsComponentException : Exception
        {
        }

        private StillDesign.PhysX.Actor _body;
        public StillDesign.PhysX.Actor Body
        {
            get { return _body; }
            set { _body = value; _body.UserData = Parent; if (_needToSetScale) notifyActorScaleChanged(); }
        }

        public StillDesign.PhysX.Scene Scene = null;

        private bool _needToSetScale = false;
        private Vector3 _prevActorScale = Vector3.One;

        public PhysicsComponent()
        {
            UpdateGroup = EUpdateGroup.PreUpdate;
            CanAffectParentAxis = true;
        }

        protected override void parentSet()
        {
            base.parentSet();

            if (Parent == null)
                return;

            if (Body != null)
                throw new PhysicsComponentException();

            Scene = Parent.Scene.PhysicsScene;
        }

        public override void Update(float dt)
        {
            if (Body != null)
            {
                Parent.Axis = (Body.Mass > 0.0f) ? Matrix.CreateScale(Parent.Scale) * Body.GlobalPose : Body.GlobalPose;
                //_body.Shapes[0].
            }
        }

        public override void notifyActorScaleChanged()
        {
            foreach (StillDesign.PhysX.Shape shape in _body.Shapes)
            {
                if (shape.Type == StillDesign.PhysX.ShapeType.Box)
                {
                    StillDesign.PhysX.BoxShape boxShape = (StillDesign.PhysX.BoxShape)shape;
                    Vector3 oldDimensions = boxShape.Dimensions;
                    boxShape.Dimensions = oldDimensions * Parent.Scale;
                }
                else
                if (shape.Type == StillDesign.PhysX.ShapeType.Sphere)
                {
                    StillDesign.PhysX.SphereShape sphereShape = (StillDesign.PhysX.SphereShape)shape;
                    float oldRadius = sphereShape.Radius;
                    sphereShape.Radius = oldRadius * (Parent.Scale.Length() / 3.0f);
                }
                else
                if (shape.Type == StillDesign.PhysX.ShapeType.Convex)
                {
                    StillDesign.PhysX.ConvexShape convexShape = (StillDesign.PhysX.ConvexShape)shape;

                }
                else
                if (shape.Type == StillDesign.PhysX.ShapeType.Mesh)
                {
                    StillDesign.PhysX.TriangleMeshShape meshShape = (StillDesign.PhysX.TriangleMeshShape)shape;

                }
            }
        }

        public override void MapFullyLoaded(TestXNA3.Generic.Map map)
        {
            base.MapFullyLoaded(map);
        }

        public override void notifyActorAxisChanged()
        {
            base.notifyActorAxisChanged();
            if (Body != null)
                Body.GlobalPose = Parent.Axis;
        }

        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
        }
    }
}
